// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';
import { dirname } from 'path';

var saved_scan_path: string;
var saved_custom_require: string;
var dicCustomRequire: { [key: string]: string } = {};
var dicRequire: { [key: string]: string } = {};
var reg = /^local[\t ]+(\w+)[\t ]*=[\t ]*([\w\.\(\)" ']+)/gm;
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
	console.error("插件启动！");
	//弹出提示
	vscode.window.showInformationMessage("插件启动！");
	// //扫描
	// context.subscriptions.push(vscode.commands.registerTextEditorCommand('lua-set-local-global.scan', (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, args: any) => {
	// 	scan_dir(true);
	// }));

	context.subscriptions.push(vscode.commands.registerTextEditorCommand('lua-set-local-global.reloadCustom', (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, args: any) => {
		reloadCustom();
	}));

	context.subscriptions.push(vscode.commands.registerTextEditorCommand('lua-set-local-global.set', (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, args: any) => {
		if (textEditor.selections.length > 1) {
			vscode.window.showErrorMessage("选择个数超过1个！");
			return;
		}

		
		if (textEditor.selection.start.line !== textEditor.selection.end.line) {
			vscode.window.showErrorMessage("选择行数超过1行！");
			return;
		}
		let selection = textEditor.selection;
		let line = textEditor.document.lineAt(textEditor.selection.start.line);
		let left = textEditor.document.getText(new vscode.Range(line.range.start, selection.start));
		let right = textEditor.document.getText(new vscode.Range(selection.end, line.range.end));
		let strLine = line.text;
		let m = left.match(/(\w+)$/);
		let strLeft = "";
		if (m) {
			strLeft = RegExp.$1;
		}
		let m1 = right.match(/^(\w+)/);
		let strRight = "";
		if (m1) {
			strRight = RegExp.$1;
		}

		let strSelection = strLine.substring(selection.start.character, selection.end.character);
		strSelection = strLeft + strSelection + strRight;
		if (strSelection.length === 0) {
			vscode.window.showErrorMessage("选中为空！");
			return;
		}
		if (strSelection.indexOf("[^\w]") >= 0) {
			vscode.window.showErrorMessage("包含非法字符");
			return;
		}
		console.error(strSelection);

		let text = textEditor.document.getText();
		let s = `local[]${strSelection}`;
		if (text.match(new RegExp(`\nlocal[\\t ]+${strSelection}[\\t ]*=[\\t ]*`))
			|| text.match(new RegExp(`^local[\\t ]+${strSelection}[\\t ]*=[\\t ]*`))
		) {
			vscode.window.showErrorMessage("已有！！！不再添加");
			return;
		}
		let bFind = false;
		// let insert_line = selection.start.line;
		let insert_line = 0;
		for (let index = 0; index < selection.start.line; index++) {
			insert_line = index;
			const element = textEditor.document.lineAt(index).text;
			if (element.match(/^local[\t ]\w+[\t ]*=[\t ]*((?!class).)+$/)) {
				bFind = true;
			} else {
				if (bFind) {
					break;
				}
			}
		}

		let str: string;
		let v = getCustomRequire(strSelection);
		if (v) {
			str = `local ${strSelection} = ${v}\n`;
		} else {
			let strRequire = getRequireStr(strSelection);
			str = `local ${strSelection} = ${strRequire}(\"${strSelection}\")\n`;
		}
		edit.insert(new vscode.Position(insert_line, 0), str);
		vscode.window.showInformationMessage(`插入成功【${insert_line}】:${str}`);
	}));

	// scan_dir(true);
	reloadCustom();
}

function getRequireStr(k: string) {
	let requireCustomArr = vscode.workspace.getConfiguration().get('lua-set-local-global.require') as Array<{ key: string, value: string }>;
	for (let index = 0; index < requireCustomArr.length; index++) {
		const element = requireCustomArr[index];
		if (k.match(new RegExp(element.key))) {
			return element.value;
		}
	}
	return vscode.workspace.getConfiguration().get('lua-set-local-global.defaultRequire') as string;
}

function getCustomRequire(k: string) {
	let v = dicCustomRequire[k];
	if (v) {
		return v;
	}
	let k_xx = formatKey(k);
	return dicCustomRequire[k_xx];
}

function formatKey(k: string) {
	return k.replace(/_/g, "").toLowerCase();
}

function get_example_path() {
	return vscode.workspace.getConfiguration().get('lua-set-local-global.custom') as string;
}

function reloadCustom() {
	let examplePath = get_example_path();
	vscode.window.showInformationMessage(`自定义文件：${examplePath}`);
	saved_custom_require = examplePath;
	let targetFile = get_path(examplePath);
	//上一级目录
	if (!targetFile) {
		vscode.window.showInformationMessage(`lua-set-local-global 未定义文件路径`);
		return;
	}

	if (!fs.existsSync(targetFile)) {
		vscode.window.showInformationMessage(`自定义文件不存在,${targetFile}`);
		return;
	}
	let targetText = fs.readFileSync(targetFile).toString();
	console.log("打开自定义文件成功:", targetFile);
	add_require(targetText, reg);
}

function add_require(targetText: string, reg: RegExp) {
	console.error("targetText", targetText);
	let r: RegExpExecArray | null;
	while (r = reg.exec(targetText)) {
		let k = r[1];
		// let str_xx = formatKey(k);
		dicCustomRequire[k] = r[2];
		console.error(k, r[2]);
		// dicCustomRequire[str_xx] = r[2];
	}
}

function scan_dir(bForce: boolean) {
	let dir = vscode.workspace.getConfiguration().get('lua-set-local-global.scan') as string;
	//弹出提示
	vscode.window.showInformationMessage(`扫描目录：${dir}`);
	if (!bForce && saved_scan_path === dir) {
		let bResult = true;
		let examplePath = get_example_path();
		if (!bForce && saved_custom_require === examplePath) {
			return;
		}
	}

	saved_scan_path = dir;

	dicRequire = {};
	let scan_dir = get_path(dir);
	if (!scan_dir) {
		vscode.window.showErrorMessage(`scan_dir是空`);
		return;
	}
	if (!fs.existsSync(scan_dir)) {
		vscode.window.showErrorMessage(`scan_dir目录文件未找到,${scan_dir}`);
		return;
	}

	//判断路径是文件加还是文件
	let states = fs.statSync(scan_dir);
	if (states.isFile()) {
		let file_text = fs.readFileSync(scan_dir).toString();
		add_require(file_text, reg);
	} else {
		let file_path: string;
		let file_text: string;
		walkDir(scan_dir, (file: string, filename: string) => {
			file_path = file + '/' + filename;
			file_text = fs.readFileSync(file_path).toString();
			add_require(file_text, reg);
		});
	}
	vscode.window.showInformationMessage(`扫描完成`);
	reloadCustom();
	vscode.window.showInformationMessage("扫描数量：" + Object.getOwnPropertyNames(dicRequire).length);
	write_require_file();
}

function write_require_file() {
	//写入
	let targetFile = get_path(vscode.workspace.getConfiguration().get("lua-set-local-global.scan_out_file") as string);
	if (!targetFile) {
		vscode.window.showErrorMessage(`lua-set-local-global 未定义文件路径`);
		return;
	}

	let dir_name = path.dirname(targetFile);
	if (!fs.existsSync(dir_name)) {
		fs.mkdirSync(dir_name);
	}
	let arr: string[] = [];
	for (const key in dicRequire) {
		if (Object.prototype.hasOwnProperty.call(dicRequire, key)) {
			const element = dicRequire[key];
			arr.push(`local ${key} = ${element}`);
		}
	}
	fs.writeFileSync(targetFile, arr.join("\n"))
	vscode.window.showInformationMessage(`扫描完成，写入文件【${targetFile}】`);
}

/**
 * 获取文件夹大小，单位字节
 * @param file 文件夹路径
 */
let sumSize = 0;
function walkDir(file: string, callback: (file: string, filename: string) => void) {
	let files = fs.readdirSync(file);
	files.forEach(function (filename: any, index: any) {
		let states = fs.statSync(file + '/' + filename);
		if (states.isDirectory()) {
			walkDir(file + '/' + filename, callback);
		} else {
			callback(file, filename);
		}
	});
}

function get_path(target_path: string) {
	if (!vscode.window.activeTextEditor) {
		console.error("未打开编辑器！");
		return;
	}
	if (!target_path || target_path.length === 0) {
		console.error("传入参数为空");
		return;
	}
	let resolvePath = path.resolve(target_path);
	if (target_path.indexOf(':') < 0) {
		let varPath = vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri);
		if (!varPath) {
			vscode.window.showInformationMessage(`未打开工程，请设置绝对路径,${target_path}`);
			return;
		} else {
			target_path = path.join(varPath.uri.fsPath, target_path);
		}
	}
	return target_path;
}

// this method is called when your extension is deactivated
export function deactivate() {
	console.log(`您的扩展"fguibind"已被释放！！！`);
}
